package org.stragma.apply.signatures

object Apply {

	import scala.collection.mutable._

    import aterm._
    import aterm.pure.SingletonFactory
    import scala.collection.mutable.ListBuffer

    case class None () extends TEExp
    case class TExpToTEExp (arg0 : TExp) extends TEExp
    case class Index () extends TLoopType
    case class RowColumn () extends TLoopType
    case class MergeComplexMultiply () extends TCompilerOption
    case class Dummy () extends TCompilerOption
    case class CFor (arg0 : TEExp, arg1 : TExp, arg2 : TEExp, arg3 : TStatements) extends TStatement
	case class CFor1 (arg0 : TStatements, arg1 : TExp, arg2 : TStatements, arg3 : TStatements) extends TStatement
    case class IfKnownStmt (arg0 : TExp, arg1 : TStatements, arg2 : TStatements) extends TStatement
    case class Attribute (arg0 : TExp, arg1 : TStatements) extends TStatement
    case class ApplyLoop (arg0 : TLoopType, arg1 : TExp, arg2 : TExp, arg3 : TExp, arg4 : TExp, arg5 : TStatements) extends TStatement
    case class Comment (arg0 : TCommentStatement) extends TStatement
    case class Assert (arg0 : TExp) extends TStatement
    case class While (arg0 : TExp, arg1 : TStatements) extends TStatement
    case class For (arg0 : TVar, arg1 : TExp, arg2 : TExp, arg3 : TStatements) extends TStatement
    case class IfElse (arg0 : TExp, arg1 : TStatements, arg2 : TStatements) extends TStatement
    case class If (arg0 : TExp, arg1 : TStatements) extends TStatement
    case class Assign (arg0 : TScalarVar, arg1 : TExp) extends TStatement
	case class Statements (arg0 : List[TStatement]) extends TStatements
	case class VarList (arg0 : List[TVar]) extends TVarList
    case class Declaration1 (arg0 : TVar, arg1 : TType) extends TDeclaration
    case class Declaration (arg0 : TVarList, arg1 : TType) extends TDeclaration
    case class Declarations (arg0 : List[TDeclaration]) extends TDeclarations
    case class ListTRangeToTRangeList (arg0 : List[TRange]) extends TRangeList
    case class Border (arg0 : TType, arg1 : TExp) extends TType
    case class Integer () extends TType
    case class Real () extends TType
    case class Byte () extends TType
    case class Array (arg0 : TRangeList, arg1 : TType) extends TType
    case class FunctionPtr () extends TArgType
    case class Type (arg0 : TType) extends TArgType
    case class Window (arg0 : TType) extends TArgType
    case class WindowArray (arg0 : TRange, arg1 : TRange, arg2 : TType) extends TArgType
    case class InOut (arg0 : TVarList, arg1 : TArgType) extends TFunctionArg
    case class Out (arg0 : TVarList, arg1 : TArgType) extends TFunctionArg
    case class In (arg0 : TVarList, arg1 : TArgType) extends TFunctionArg
    case class Arguments (arg0 : List[TFunctionArg]) extends TFunctionArgs
    case class Procedure (arg0 : TVar, arg1 : TFunctionArgs, arg2 : TDeclarations, arg3 : TStatements, arg4 : TVar) extends TFunction
    case class Option (arg0 : TCompilerOption) extends TFunction
    case class Module (arg0 : List[TFunction]) extends TModule
    case class TVarToTScalarVar (arg0 : TVar) extends TScalarVar
    case class Func (arg0 : TVar, arg1 : TExp) extends TScalarVar
    case class Var (arg0 : TId) extends TVar
    case class Range (arg0 : TExp) extends TRangeExp
    case class Range1 (arg0 : TExp, arg1 : TExp) extends TRangeExp
    case class Range2 (arg0 : TExp, arg1 : TExp) extends TRange
    case class CAssign (arg0 : TVar, arg1 : TExp) extends TExp
    case class IfElseExp (arg0 : TExp, arg1 : TExp, arg2 : TExp) extends TExp
    case class Known (arg0 : TExp) extends TExp
    case class IfKnownExp (arg0 : TExp, arg1 : TExp, arg2 : TExp) extends TExp
    case class Defined (arg0 : TVar, arg1 : TRangeExp, arg2 : TRangeExp) extends TExp
    case class TScalarVarToTExp (arg0 : TScalarVar) extends TExp
    case class Comma (arg0 : TExp, arg1 : TExp) extends TExp
    case class Or (arg0 : TExp, arg1 : TExp) extends TExp
    case class And (arg0 : TExp, arg1 : TExp) extends TExp
    case class BitOr (arg0 : TExp, arg1 : TExp) extends TExp
    case class BitAnd (arg0 : TExp, arg1 : TExp) extends TExp
    case class Neq (arg0 : TExp, arg1 : TExp) extends TExp
    case class Equ (arg0 : TExp, arg1 : TExp) extends TExp
    case class Geq (arg0 : TExp, arg1 : TExp) extends TExp
    case class Leq (arg0 : TExp, arg1 : TExp) extends TExp
    case class Gt (arg0 : TExp, arg1 : TExp) extends TExp
    case class Lt (arg0 : TExp, arg1 : TExp) extends TExp
    case class Neg (arg0 : TExp) extends TExp
    case class Sub (arg0 : TExp, arg1 : TExp) extends TExp
	case class Sub1(arg0 : TVar, arg1 : TExp) extends TExp
    case class Add (arg0 : TExp, arg1 : TExp) extends TExp
	case class Add1(arg0 : TVar, arg1 : TExp) extends TExp
    case class Mod (arg0 : TExp, arg1 : TExp) extends TExp
    case class Div (arg0 : TExp, arg1 : TExp) extends TExp
    case class Mul (arg0 : TExp, arg1 : TExp) extends TExp
    case class Real1 (arg0 : TRealConst) extends TExp
    case class Int (arg0 : TIntConst) extends TExp
    case class Not (arg0 : TExp) extends TExp
    case class False () extends TExp
    case class True () extends TExp

    case class WindowAccessScalar (arg0 : TVar, arg1 : TType) extends TVar
    case class WindowAccessScalar1 (arg0 : TVar, arg1 : TType, arg2 : String) extends TVar
	case class WindowAccessScalar2 (arg0 : TVar, arg1 : TType, arg2 : TLoopType) extends TVar
    case class WindowAccessElement (arg0 : TVar, arg1 : TExp, arg2 : TExp, arg3 : TRange, arg4 : TRange, arg5 : TType) extends TVar
    case class WindowAccessElement1 (arg0 : TVar, arg1 : TExp, arg2 : TExp, arg3 : TRange, arg4 : TRange, arg5 : TType, arg6 : TLoopType) extends TVar

    case class Subscript (arg0 : TVar, arg1 : TExp) extends TVar
    case class Argument (arg0 : TVar, arg1 : TArgType) extends TFunctionArg
    case class Argument1 (arg0 : TVarList, arg1 : TArgType) extends TFunctionArg
    case class Access (arg0 : String, arg1 : TArgType) extends TArgType
    case class CAccess (arg0 : String, arg1 : TArgType) extends TArgType
	case class CAccess1 (arg0 : String, arg1 : TVar) extends TArgType
    case class CArgument (arg0 : TArgType, arg1 : TArgType) extends TFunctionArg
    case class CDeclaration (arg0 : TType, arg1 : TType) extends TDeclaration
    case class TVarToTType (arg0 : TVar) extends TType
    case class ListTExpToTExpList (arg0 : List[TExp]) extends TExpList

	case class CArray (arg0 : TType, arg1 : TExpList) extends TType
    case class CArray1 (arg0 : TArgType, arg1 : TExpList) extends TType
    
	case class TTypeToTArgType (arg0 : TType) extends TArgType
	case class TArgTypeToTType (arg0 : TArgType) extends TType
    case class CBorder (arg0 : TExp, arg1 : TArgType) extends TArgType
    case class CFunctionPtr (arg0 : TVar) extends TType
    case class CIncrementExp (arg0 : TVar, arg1 : TExp) extends TExp
    case class CIncrementExp1 (arg0 : TVar) extends TExp
    case class CDecrementExp (arg0 : TVar) extends TExp
    case class CIncrementStmt (arg0 : TVar, arg1 : TExp) extends TStatement
    case class CIncrementStmt1 (arg0 : TVar) extends TStatement
    case class Statement (arg0 : TExp) extends TStatement

	case class Parenthetical(arg0 : TExp) extends TExp
	case class Parenthetical1(arg0 : TVar) extends TVar
	
    type TRealConst = String
    type TIntConst = String
    type TId = String
    type TCommentStatement = String

    abstract class TRangeExp extends TBase
    abstract class TVar extends TBase
    abstract class TStatements extends TBase
    abstract class TRangeList extends TBase
    abstract class TDeclaration extends TBase
    abstract class TCompilerOption extends TBase
    abstract class TFunctionArg extends TBase
    abstract class TLoopType extends TBase
    abstract class TRange extends TBase
    abstract class TModule extends TBase
    abstract class TString extends TBase
    abstract class TFunction extends TBase
    abstract class TExpList extends TBase
    abstract class TArgType extends TBase
    abstract class TDeclarations extends TBase

		/**
		 *	This bit of code was not created by Sig2Scala
		 * 	it has been done by hand to enhance the readability
		 *  of the rewriting functions
		 */
    abstract class TExp extends TBase {
	
			def and (arg1 : TExp) = And(this, arg1)
			def or (arg1 : TExp) = Or(this, arg1)
		
			/**
		 	 * Now some of the mathematical operators
		 	 */
			def - (arg1 : TExp) = Sub (this, arg1)
			def * (arg1 : TExp) = Mul (this, arg1)
			def + (arg1 : TExp) = Add (this, arg1)
			def / (arg1 : TExp) = Div (this, arg1)
		
			/**
		 	 * Construct a list from 2 TExp
		 	 */
			def :: (arg1 : TExp) = {
				val buffer : ListBuffer[TExp] = ListBuffer[TExp]()
				buffer += this += arg1
				buffer.toList
		}
	}

    abstract class TStatement extends TBase
    abstract class TVarList extends TBase

    abstract class TEExp extends TBase
    abstract class TFunctionArgs extends TBase
    abstract class TScalarVar extends TBase
    abstract class TType extends TBase

     def ATermToTRangeExp (term : ATerm) : TRangeExp =
        term match {
            case t : ATermAppl =>
                val args = t.getArgumentArray ()
                t.getName match {
                    case "Range" if (args.length == 1) => 
                        val arg0 = ATermToTExp (args (0))
                        Range (arg0)
                    case "Range" if (args.length == 2) => 
                        val arg0 = ATermToTExp (args (0))
                        val arg1 = ATermToTExp (args (1))
                        Range1 (arg0, arg1)
                    case n =>
                        sys.error ("unknown constructor " + n + " for TRangeExp found")
                }
            case _ =>
                sys.error ("non-application aterm found for TRangeExp: " + term)
        }

    def ATermToTScalarVar (term : ATerm) : TScalarVar =
        term match {
            case t : ATermAppl =>
                val args = t.getArgumentArray ()
                t.getName match {
                    case "Func" if (args.length == 2) => 
                        val arg0 = ATermToTVar (args (0))
                        val arg1 = ATermToTExp (args (1))
                        Func (arg0, arg1)
                    case "Var" | "WindowAccessElement" | "WindowAccessElement1" | "WindowAccessScalar1" | "Subscript" | "WindowAccessScalar" =>
                        val arg0 = ATermToTVar (term)
                        TVarToTScalarVar (arg0)
                    case n =>
                        sys.error ("unknown constructor " + n + " for TScalarVar found")
                }
            case _ =>
                sys.error ("non-application aterm found for TScalarVar: " + term)
        }

    def ATermToTArgType (term : ATerm) : TArgType =
        term match {
            case t : ATermAppl =>
                val args = t.getArgumentArray ()
                t.getName match {
                    case "Window" if (args.length == 1) => 
                        val arg0 = ATermToTType (args (0))
                        Window (arg0)
                    case "FunctionPtr" if (args.length == 0) => 
                        FunctionPtr ()
                    case "Access" if (args.length == 2) => 
                        val arg0 = ATermToString (args (0))
                        val arg1 = ATermToTArgType (args (1))
                        Access (arg0, arg1)
                    case "CAccess" if (args.length == 2) => 
                        val arg0 = ATermToString (args (0))
                        val arg1 = ATermToTArgType (args (1))
                        CAccess (arg0, arg1)
                    case "Type" if (args.length == 1) => 
                        val arg0 = ATermToTType (args (0))
                        Type (arg0)
                    case "WindowArray" if (args.length == 3) => 
                        val arg0 = ATermToTRange (args (0))
                        val arg1 = ATermToTRange (args (1))
                        val arg2 = ATermToTType (args (2))
                        WindowArray (arg0, arg1, arg2)
                    /*case "CArgument" if (args.length == 2) => 
                        val arg0 = ATermToTArgType (args (0))
                        val arg1 = ATermToTArgType (args (1))
                        CArgument (arg0, arg1)*/
                    case "CBorder" if (args.length == 2) => 
                        val arg0 = ATermToTExp (args (0))
                        val arg1 = ATermToTArgType (args (1))
                        CBorder (arg0, arg1)
                    case "Real" | "Border" | "CFunctionPtr" | "CArray" | "CDeclaration" | "Byte" | "Array" | "Integer" | "Var" | "WindowAccessElement" | "WindowAccessElement1" | "WindowAccessScalar1" | "Subscript" | "WindowAccessScalar" =>
                        val arg0 = ATermToTType (term)
                        TTypeToTArgType (arg0)
                    case n =>
                        sys.error ("unknown constructor " + n + " for TArgType found")
                }
            case _ =>
                sys.error ("non-application aterm found for TArgType: " + term)
        }

    def ATermToTEExp (term : ATerm) : TEExp =
        term match {
            case t : ATermAppl =>
                val args = t.getArgumentArray ()
                t.getName match {
                    case "None" if (args.length == 0) => 
                        None ()
                    case "Not" | "Mod" | "And" | "BitAnd" | "Mul" | "Neg" | "False" | "Real1" | "CDecrementExp" | "IfElseExp" | "BitOr" | "Leq" | "Sub" | "Lt" | "Equ" | "Geq" | "IfKnownExp" | "Known" | "Int" | "Neq" | "CAssign" | "CIncrementExp1" | "Gt" | "Add" | "Defined" | "True" | "Comma" | "Or" | "Div" | "CIncrementExp" | "Func" | "Var" | "WindowAccessElement" | "WindowAccessElement1" | "WindowAccessScalar1" | "Subscript" | "WindowAccessScalar" =>
                        val arg0 = ATermToTExp (term)
                        TExpToTEExp (arg0)
                    case n =>
                        sys.error ("unknown constructor " + n + " for TEExp found")
                }
            case _ =>
                sys.error ("non-application aterm found for TEExp: " + term)
        }

    def ATermToTExpList (term : ATerm) : TExpList =
        term match {
            case t : ATermAppl =>
                val args = t.getArgumentArray ()
                t.getName match {
                    case n =>
                        sys.error ("unknown constructor " + n + " for TExpList found")
                }
            case t : ATermList =>
                val arg0 = ATermToListTExp (term)
                ListTExpToTExpList (arg0)
            case _ =>
                sys.error ("non-application aterm found for TExpList: " + term)
        }

    def ATermToTExp (term : ATerm) : TExp =
        term match {
            case t : ATermAppl =>
                val args = t.getArgumentArray ()
                t.getName match {
                    case "Not" if (args.length == 1) => 
                        val arg0 = ATermToTExp (args (0))
                        Not (arg0)
                    case "Mod" if (args.length == 2) => 
                        val arg0 = ATermToTExp (args (0))
                        val arg1 = ATermToTExp (args (1))
                        Mod (arg0, arg1)
                    case "And" if (args.length == 2) => 
                        val arg0 = ATermToTExp (args (0))
                        val arg1 = ATermToTExp (args (1))
                        And (arg0, arg1)
                    case "BitAnd" if (args.length == 2) => 
                        val arg0 = ATermToTExp (args (0))
                        val arg1 = ATermToTExp (args (1))
                        BitAnd (arg0, arg1)
                    case "Mul" if (args.length == 2) => 
                        val arg0 = ATermToTExp (args (0))
                        val arg1 = ATermToTExp (args (1))
                        Mul (arg0, arg1)
                    case "Neg" if (args.length == 1) => 
                        val arg0 = ATermToTExp (args (0))
                        Neg (arg0)
                    case "False" if (args.length == 0) => 
                        False ()
                    case "Real" if (args.length == 1) => 
                        val arg0 = ATermToTRealConst (args (0))
                        Real1 (arg0)
                    case "CDecrementExp" if (args.length == 1) => 
                        val arg0 = ATermToTVar (args (0))
                        CDecrementExp (arg0)
                    case "IfElseExp" if (args.length == 3) => 
                        val arg0 = ATermToTExp (args (0))
                        val arg1 = ATermToTExp (args (1))
                        val arg2 = ATermToTExp (args (2))
                        IfElseExp (arg0, arg1, arg2)
                    case "BitOr" if (args.length == 2) => 
                        val arg0 = ATermToTExp (args (0))
                        val arg1 = ATermToTExp (args (1))
                        BitOr (arg0, arg1)
                    case "Leq" if (args.length == 2) => 
                        val arg0 = ATermToTExp (args (0))
                        val arg1 = ATermToTExp (args (1))
                        Leq (arg0, arg1)
                    case "Sub" if (args.length == 2) => 
                        val arg0 = ATermToTExp (args (0))
                        val arg1 = ATermToTExp (args (1))
                        Sub (arg0, arg1)
                    case "Lt" if (args.length == 2) => 
                        val arg0 = ATermToTExp (args (0))
                        val arg1 = ATermToTExp (args (1))
                        Lt (arg0, arg1)
                    case "Equ" if (args.length == 2) => 
                        val arg0 = ATermToTExp (args (0))
                        val arg1 = ATermToTExp (args (1))
                        Equ (arg0, arg1)
                    case "Geq" if (args.length == 2) => 
                        val arg0 = ATermToTExp (args (0))
                        val arg1 = ATermToTExp (args (1))
                        Geq (arg0, arg1)
                    case "IfKnownExp" if (args.length == 3) => 
                        val arg0 = ATermToTExp (args (0))
                        val arg1 = ATermToTExp (args (1))
                        val arg2 = ATermToTExp (args (2))
                        IfKnownExp (arg0, arg1, arg2)
                    case "Known" if (args.length == 1) => 
                        val arg0 = ATermToTExp (args (0))
                        Known (arg0)
                    case "Int" if (args.length == 1) => 
                        val arg0 = ATermToTIntConst (args (0))
                        Int (arg0)
                    case "Neq" if (args.length == 2) => 
                        val arg0 = ATermToTExp (args (0))
                        val arg1 = ATermToTExp (args (1))
                        Neq (arg0, arg1)
                    case "CAssign" if (args.length == 2) => 
                        val arg0 = ATermToTVar (args (0))
                        val arg1 = ATermToTExp (args (1))
                        CAssign (arg0, arg1)
                    case "CIncrementExp" if (args.length == 1) => 
                        val arg0 = ATermToTVar (args (0))
                        CIncrementExp1 (arg0)
                    case "Gt" if (args.length == 2) => 
                        val arg0 = ATermToTExp (args (0))
                        val arg1 = ATermToTExp (args (1))
                        Gt (arg0, arg1)
                    case "Add" if (args.length == 2) => 
                        val arg0 = ATermToTExp (args (0))
                        val arg1 = ATermToTExp (args (1))
                        Add (arg0, arg1)
                    case "Defined" if (args.length == 3) => 
                        val arg0 = ATermToTVar (args (0))
                        val arg1 = ATermToTRangeExp (args (1))
                        val arg2 = ATermToTRangeExp (args (2))
                        Defined (arg0, arg1, arg2)
                    case "True" if (args.length == 0) => 
                        True ()
                    case "Comma" if (args.length == 2) => 
                        val arg0 = ATermToTExp (args (0))
                        val arg1 = ATermToTExp (args (1))
                        Comma (arg0, arg1)
                    case "Or" if (args.length == 2) => 
                        val arg0 = ATermToTExp (args (0))
                        val arg1 = ATermToTExp (args (1))
                        Or (arg0, arg1)
                    case "Div" if (args.length == 2) => 
                        val arg0 = ATermToTExp (args (0))
                        val arg1 = ATermToTExp (args (1))
                        Div (arg0, arg1)
                    case "CIncrementExp" if (args.length == 2) => 
                        val arg0 = ATermToTVar (args (0))
                        val arg1 = ATermToTExp (args (1))
                        CIncrementExp (arg0, arg1)
                    case "Func" | "Var" | "WindowAccessElement" | "WindowAccessElement1" | "WindowAccessScalar1" | "Subscript" | "WindowAccessScalar" =>
                        val arg0 = ATermToTScalarVar (term)
                        TScalarVarToTExp (arg0)
                    case n =>
                        sys.error ("unknown constructor " + n + " for TExp found")
                }
            case _ =>
                sys.error ("non-application aterm found for TExp: " + term)
        }

    def ATermToTDeclarations (term : ATerm) : TDeclarations =
        term match {
            case t : ATermAppl =>
                val args = t.getArgumentArray ()
                t.getName match {
                    case "Declarations" if (args.length == 1) => 
                        val arg0 = ATermToListTDeclaration (args (0))
                        Declarations (arg0)
                    case n =>
                        sys.error ("unknown constructor " + n + " for TDeclarations found")
                }
			case t : ATermList =>
				// Need to flatten the list
				val b = new ListBuffer[TDeclaration] ()
                for (i <- 0 until t.getLength) {
					t.elementAt (i) match {
   						case item : ATermAppl =>
							val args = item.getArgumentArray ()
            				item.getName match {
								case "Declarations" if (args.length == 1) =>
									val arg0 = ATermToListTDeclaration (args(0))
									arg0 foreach { arg => b += arg }
								case _ =>
									b += ATermToTDeclaration (t.elementAt (i))
							}
						}
				}
                Declarations(b.result)
            case _ =>
                sys.error ("non-application aterm found for TDeclarations: " + term)
        }

    def ATermToTType (term : ATerm) : TType =
        term match {
        		case t : ATermAppl =>
                val args = t.getArgumentArray ()
                t.getName match {
					case "Type" if (args.length == 1) =>
						ATermToTType(args(0))
        			case "Real" if (args.length == 0) => 
						Real ()
					case "Border" if (args.length == 2) => 
            			val arg0 = ATermToTType (args (0))
                		val arg1 = ATermToTExp (args (1))
                		Border (arg0, arg1)
            		case "CFunctionPtr" if (args.length == 1) => 
            			val arg0 = ATermToTVar (args (0))
                		CFunctionPtr (arg0)
            		case "CArray" if (args.length == 2) => 
						try {
                			val arg0 = ATermToTType (args (0))
                  			val arg1 = ATermToTExpList (args (1))
                  			CArray (arg0, arg1)
						} catch {
							// HACK
							case e =>
								val arg2 = ATermToTArgType (args (0))
								val arg3 = ATermToTExpList (args (1))
								CArray1 (arg2, arg3)
						}
           			case "Byte" if (args.length == 0) => 
           				Byte ()
           			case "Array" if (args.length == 2) => 
           				val arg0 = ATermToTRangeList (args (0))
                		val arg1 = ATermToTType (args (1))
                		Array (arg0, arg1)
					case "Integer" if (args.length == 0) => 
          				Integer ()
          			case "Var" | "WindowAccessElement" | "WindowAccessElement1" | "WindowAccessScalar1" | "Subscript" | "WindowAccessScalar" =>
          				val arg0 = ATermToTVar (term)
                		TVarToTType (arg0)
					case n =>
          				sys.error ("unknown constructor " + n + " for TType found")
           }
            case _ =>
                sys.error ("non-application aterm found for TType: " + term)
        }

    def ATermToTFunctionArgs (term : ATerm) : TFunctionArgs =
        term match {
            case t : ATermAppl =>
                val args = t.getArgumentArray ()
                t.getName match {
                    case "Arguments" if (args.length == 1) => 
                        val arg0 = ATermToListTFunctionArg (args (0))
                        Arguments (arg0)
                    case n =>
                        sys.error ("unknown constructor " + n + " for TFunctionArgs found")
                }
            case _ =>
                sys.error ("non-application aterm found for TFunctionArgs: " + term)
        }

    def ATermToTVar (term : ATerm) : TVar =
        term match {
            case t : ATermAppl =>
                val args = t.getArgumentArray ()
                t.getName match {
                    case "Var" if (args.length == 1) => 
                        val arg0 = ATermToTId (args (0))
                        Var (arg0)
                    case "WindowAccessElement" if (args.length == 6) => 
                        val arg0 = ATermToTVar (args (0))
                        val arg1 = ATermToTExp (args (1))
                        val arg2 = ATermToTExp (args (2))
                        val arg3 = ATermToTRange (args (3))
                        val arg4 = ATermToTRange (args (4))
                        val arg5 = ATermToTType (args (5))
                        WindowAccessElement (arg0, arg1, arg2, arg3, arg4, arg5)
                    case "WindowAccessElement" if (args.length == 7) => 
                        val arg0 = ATermToTVar (args (0))
                        val arg1 = ATermToTExp (args (1))
                        val arg2 = ATermToTExp (args (2))
                        val arg3 = ATermToTRange (args (3))
                        val arg4 = ATermToTRange (args (4))
                        val arg5 = ATermToTType (args (5))
                        val arg6 = ATermToTLoopType (args (6))
                        WindowAccessElement1 (arg0, arg1, arg2, arg3, arg4, arg5, arg6)
                    case "WindowAccessScalar" if (args.length == 3) => 
                        val arg0 = ATermToTVar (args (0))
                        val arg1 = ATermToTType (args (1))
                        val arg2 = ATermToString (args (2))
                        WindowAccessScalar1 (arg0, arg1, arg2)
                    case "Subscript" if (args.length == 2) => 
                        val arg0 = ATermToTVar (args (0))
                        val arg1 = ATermToTExp (args (1))
                        Subscript (arg0, arg1)
                    case "WindowAccessScalar" if (args.length == 2) => 
                        val arg0 = ATermToTVar (args (0))
                        val arg1 = ATermToTType (args (1))
                        WindowAccessScalar (arg0, arg1)
                    case n =>
                        sys.error ("unknown constructor " + n + " for TVar found")
                }
            case _ =>
                sys.error ("non-application aterm found for TVar: " + term)
        }

    def ATermToTModule (term : ATerm) : TModule =
        term match {
            case t : ATermAppl =>
                val args = t.getArgumentArray ()
                t.getName match {
                    case "Module" if (args.length == 1) => 
                        val arg0 = ATermToListTFunction (args (0))
                        Module (arg0)
                    case n =>
                        sys.error ("unknown constructor " + n + " for TModule found")
                }
            case _ =>
                sys.error ("non-application aterm found for TModule: " + term)
        }

    def ATermToTFunction (term : ATerm) : TFunction =
        term match {
            case t : ATermAppl =>
                val args = t.getArgumentArray ()
                t.getName match {
                    case "Option" if (args.length == 1) => 
                        val arg0 = ATermToTCompilerOption (args (0))
                        Option (arg0)
                    case "Procedure" if (args.length == 5) => 
                        val arg0 = ATermToTVar (args (0))
                        val arg1 = ATermToTFunctionArgs (args (1))
                        val arg2 = ATermToTDeclarations (args (2))
                        val arg3 = ATermToTStatements (args (3))
                        val arg4 = ATermToTVar (args (4))
                        Procedure (arg0, arg1, arg2, arg3, arg4)
                    case n =>
                        sys.error ("unknown constructor " + n + " for TFunction found")
                }
            case _ =>
                sys.error ("non-application aterm found for TFunction: " + term)
        }

    def ATermToTCompilerOption (term : ATerm) : TCompilerOption =
        term match {
            case t : ATermAppl =>
                val args = t.getArgumentArray ()
                t.getName match {
                    case "Dummy" if (args.length == 0) => 
                        Dummy ()
                    case "MergeComplexMultiply" if (args.length == 0) => 
                        MergeComplexMultiply ()
                    case n =>
                        sys.error ("unknown constructor " + n + " for TCompilerOption found")
                }
            case _ =>
                sys.error ("non-application aterm found for TCompilerOption: " + term)
        }

    def ATermToTFunctionArg (term : ATerm) : TFunctionArg =
        term match {
            case t : ATermAppl =>
                val args = t.getArgumentArray ()
                t.getName match {
                    case "Argument" if (args.length == 2) => 
                        val arg0 = ATermToTVar (args (0))
                        val arg1 = ATermToTArgType (args (1))
                        Argument (arg0, arg1)
                    case "Argument" if (args.length == 2) => 
                        val arg0 = ATermToTVarList (args (0))
                        val arg1 = ATermToTArgType (args (1))
                        Argument1 (arg0, arg1)
                    case "InOut" if (args.length == 2) => 
                        val arg0 = ATermToTVarList (args (0))
                        val arg1 = ATermToTArgType (args (1))
                        InOut (arg0, arg1)
                    case "In" if (args.length == 2) => 
                        val arg0 = ATermToTVarList (args (0))
                        val arg1 = ATermToTArgType (args (1))
                        In (arg0, arg1)
                    case "Out" if (args.length == 2) => 
                        val arg0 = ATermToTVarList (args (0))
                        val arg1 = ATermToTArgType (args (1))
                        Out (arg0, arg1)
					case "CArgument" if (args.length == 2) =>
						val arg0 = ATermToTArgType (args (0))
						val arg1 = ATermToTArgType (args (1))
						CArgument(arg0, arg1)
                    case n =>
                        sys.error ("unknown constructor " + n + " for TFunctionArg found")
                }
            case _ =>
                sys.error ("non-application aterm found for TFunctionArg: " + term)
        }

    def ATermToTLoopType (term : ATerm) : TLoopType =
        term match {
            case t : ATermAppl =>
                val args = t.getArgumentArray ()
                t.getName match {
                    case "Index" if (args.length == 0) => 
                        Index ()
                    case "RowColumn" if (args.length == 0) => 
                        RowColumn ()
                    case n =>
                        sys.error ("unknown constructor " + n + " for TLoopType found")
                }
            case _ =>
                sys.error ("non-application aterm found for TLoopType: " + term)
        }

    def ATermToTDeclaration (term : ATerm) : TDeclaration =
        term match {
            case t : ATermAppl =>
            	val args = t.getArgumentArray ()
            	t.getName match {
              	case "Declaration" if (args.length == 2) =>
					try {
                  		val arg0 = ATermToTVarList (args (0))
                  		val arg1 = ATermToTType (args (1))
                 		Declaration (arg0, arg1)
					} catch {
						// HACK:
						case e : Exception =>
							val arg0 = ATermToTVar (args (0))
                     		val arg1 = ATermToTType (args (1))
                    		Declaration1 (arg0, arg1)
					}
				case "CDeclaration" if (args.length == 2) => 
                	val arg0 = ATermToTType (args (0))
                 	val arg1 = ATermToTType (args (1))
                  	CDeclaration (arg0, arg1)
                case n =>
                	sys.error ("unknown constructor " + n + " for TDeclaration found")
               }
            case _ =>
                sys.error ("non-application aterm found for TDeclaration: " + term)
        }

    def ATermToTStatements (term : ATerm) : TStatements =
        term match {
            case t : ATermAppl =>
                val args = t.getArgumentArray ()
                t.getName match {
                    case "Statements" if (args.length == 1) => 
                        val arg0 = ATermToListTStatement (args (0))
                        Statements (arg0)
                    case n =>
                        sys.error ("unknown constructor " + n + " for TStatements found")
                }
            case _ =>
                sys.error ("non-application aterm found for TStatements: " + term)
        }

    def ATermToTRangeList (term : ATerm) : TRangeList =
        term match {
            case t : ATermAppl =>
                val args = t.getArgumentArray ()
                t.getName match {
                    case n =>
                        sys.error ("unknown constructor " + n + " for TRangeList found")
                }
            case t : ATermList =>
                val arg0 = ATermToListTRange (term)
                ListTRangeToTRangeList (arg0)
            case _ =>
                sys.error ("non-application aterm found for TRangeList: " + term)
        }

    def ATermToTRange (term : ATerm) : TRange =
        term match {
            case t : ATermAppl =>
                val args = t.getArgumentArray ()
                t.getName match {
                    case "Range" if (args.length == 2) => 
                        val arg0 = ATermToTExp (args (0))
                        val arg1 = ATermToTExp (args (1))
                        Range2 (arg0, arg1)
                    case n =>
                        sys.error ("unknown constructor " + n + " for TRange found")
                }
            case _ =>
                sys.error ("non-application aterm found for TRange: " + term)
        }

    def ATermToTStatement (term : ATerm) : TStatement =
        term match {
            case t : ATermAppl =>
                val args = t.getArgumentArray ()
                t.getName match {
                    case "Assert" if (args.length == 1) => 
                        val arg0 = ATermToTExp (args (0))
                        Assert (arg0)
                    case "Attribute" if (args.length == 2) => 
                        val arg0 = ATermToTExp (args (0))
                        val arg1 = ATermToTStatements (args (1))
                        Attribute (arg0, arg1)
                    case "While" if (args.length == 2) => 
                        val arg0 = ATermToTExp (args (0))
                        val arg1 = ATermToTStatements (args (1))
                        While (arg0, arg1)
                    case "IfKnownStmt" if (args.length == 3) => 
                        val arg0 = ATermToTExp (args (0))
                        val arg1 = ATermToTStatements (args (1))
                        val arg2 = ATermToTStatements (args (2))
                        IfKnownStmt (arg0, arg1, arg2)
                    case "IfElse" if (args.length == 3) => 
                        val arg0 = ATermToTExp (args (0))
                        val arg1 = ATermToTStatements (args (1))
                        val arg2 = ATermToTStatements (args (2))
                        IfElse (arg0, arg1, arg2)
                    case "Statement" if (args.length == 1) => 
                        val arg0 = ATermToTExp (args (0))
                        Statement (arg0)
                    case "Comment" if (args.length == 1) => 
                        val arg0 = ATermToTCommentStatement (args (0))
                        Comment (arg0)
                    case "CFor" if (args.length == 4) => 
                        val arg0 = ATermToTEExp (args (0))
                        val arg1 = ATermToTExp (args (1))
                        val arg2 = ATermToTEExp (args (2))
                        val arg3 = ATermToTStatements (args (3))
                        CFor (arg0, arg1, arg2, arg3)
                    case "CIncrementStmt" if (args.length == 2) => 
                        val arg0 = ATermToTVar (args (0))
                        val arg1 = ATermToTExp (args (1))
                        CIncrementStmt (arg0, arg1)
                    case "ApplyLoop" if (args.length == 6) => 
                        val arg0 = ATermToTLoopType (args (0))
                        val arg1 = ATermToTExp (args (1))
                        val arg2 = ATermToTExp (args (2))
                        val arg3 = ATermToTExp (args (3))
                        val arg4 = ATermToTExp (args (4))
                        val arg5 = ATermToTStatements (args (5))
                        ApplyLoop (arg0, arg1, arg2, arg3, arg4, arg5)
                    case "Assign" if (args.length == 2) => 
                        val arg0 = ATermToTScalarVar (args (0))
                        val arg1 = ATermToTExp (args (1))
                        Assign (arg0, arg1)
                    case "CIncrementStmt" if (args.length == 1) => 
                        val arg0 = ATermToTVar (args (0))
                        CIncrementStmt1 (arg0)
                    case "For" if (args.length == 4) => 
                        val arg0 = ATermToTVar (args (0))
                        val arg1 = ATermToTExp (args (1))
                        val arg2 = ATermToTExp (args (2))
                        val arg3 = ATermToTStatements (args (3))
                        For (arg0, arg1, arg2, arg3)
                    case "If" if (args.length == 2) => 
                        val arg0 = ATermToTExp (args (0))
                        val arg1 = ATermToTStatements (args (1))
                        If (arg0, arg1)
                    case n =>
                        sys.error ("unknown constructor " + n + " for TStatement found")
                }
            case _ =>
                sys.error ("non-application aterm found for TStatement: " + term)
        }

    def ATermToTVarList (term : ATerm) : TVarList =
        term match {
            case t : ATermAppl =>
                val args = t.getArgumentArray ()
                t.getName match {
                    case "VarList" if (args.length == 1) => 
                        val arg0 = ATermToListTVar (args (0))
                        VarList (arg0)
                    case n =>
                        sys.error ("unknown constructor " + n + " for TVarList found")
                }
            case _ =>
                sys.error ("non-application aterm found for TVarList: " + term)
        }

    def ATermToString (term : ATerm) : String =
        term match {
            case t : ATermAppl =>
                t.getName
            case _ =>
                sys.error ("ATermAppl expected in atermToString but " + term + " found")
        }

    def ATermToTRealConst (term : ATerm) : TRealConst =
         ATermToString (term)

    def ATermToTIntConst (term : ATerm) : TIntConst =
         ATermToString (term)

    def ATermToTId (term : ATerm) : TId =
         ATermToString (term)

    def ATermToTCommentStatement (term : ATerm) : TCommentStatement =
         ATermToString (term)

    def ATermToListTStatement (term : ATerm) : List[TStatement] =
        term match {
            case t : ATermList =>
                val b = new ListBuffer[TStatement] ()
                for (i <- 0 until t.getLength) {
					// SHIRREN: Flattening statements
					val item = t.elementAt(i)
					item match {
						case atAppl : ATermAppl =>
							val args = atAppl.getArgumentArray ()
							atAppl.getName match {
								case "Statements" =>
									val result = ATermToListTStatement(args(0))
									result foreach {
										case statement =>
											b += statement
									}
								case _ =>
									b += ATermToTStatement (t.elementAt (i))
							}
					}
                    //b += ATermToTStatement (t.elementAt (i))
				}
                b.result
            case _ =>
                sys.error ("non-list aterm found for ListTStatement: " + term)
        }

    def ATermToListTRange (term : ATerm) : List[TRange] =
        term match {
            case t : ATermList =>
                val b = new ListBuffer[TRange] ()
				// SHIRREN: Added support for arguments that are constituted using empty arrays
				// An attempt to convert [""] to a TRange fails
                for (i <- 0 until t.getLength) {
					try {
						b += ATermToTRange (t.elementAt (i))
					} catch {
						case e : Exception =>
						// Do nothing with this, it could happen
					}
				}
                b.result
            case _ =>
                sys.error ("non-list aterm found for ListTRange: " + term)
        }

    def ATermToListTDeclaration (term : ATerm) : List[TDeclaration] =
        term match {
            case t : ATermList =>
                val b = new ListBuffer[TDeclaration] ()
                for (i <- 0 until t.getLength)
                    b += ATermToTDeclaration (t.elementAt (i))
                b.result
            case _ =>
                sys.error ("non-list aterm found for ListTDeclaration: " + term)
        }

    def ATermToListTFunctionArg (term : ATerm) : List[TFunctionArg] =
        term match {
            case t : ATermList =>
                val b = new ListBuffer[TFunctionArg] ()
                for (i <- 0 until t.getLength) {
					t.elementAt (i) match {
   						case item : ATermAppl =>
							val args = item.getArgumentArray ()
            				item.getName match {
								case "Arguments" if (args.length == 1) =>
									val arg0 = ATermToListTFunctionArg (args(0))
									arg0 foreach { arg => b += arg }
								case _ =>
									b += ATermToTFunctionArg (t.elementAt (i))
							}
						}
				}
                b.result
            case _ =>
                sys.error ("non-list aterm found for ListTFunctionArg: " + term)
        }

    def ATermToListTFunction (term : ATerm) : List[TFunction] =
        term match {
            case t : ATermList =>
                val b = new ListBuffer[TFunction] ()
                for (i <- 0 until t.getLength)
                    b += ATermToTFunction (t.elementAt (i))
                b.result
            case _ =>
                sys.error ("non-list aterm found for ListTFunction: " + term)
        }

    def ATermToListTVar (term : ATerm) : List[TVar] =
        term match {
            case t : ATermList =>
                val b = new ListBuffer[TVar] ()
                for (i <- 0 until t.getLength)
                    b += ATermToTVar (t.elementAt (i))
                b.result
            case _ =>
                sys.error ("non-list aterm found for ListTVar: " + term)
        }

    def ATermToListTExp (term : ATerm) : List[TExp] =
        term match {
            case t : ATermList =>
                val b = new ListBuffer[TExp] ()
                for (i <- 0 until t.getLength)
                    b += ATermToTExp (t.elementAt (i))
                b.result
            case _ =>
                sys.error ("non-list aterm found for ListTExp: " + term)
        }

    private val f = SingletonFactory.getInstance ()

    def TRangeExpToATerm (value : TRangeExp) : ATerm =
        value match {
            case v : Range =>
                val child0 = TExpToATerm (v.arg0)
                val fun = f.makeAFun ("Range", 1, false)
                f.makeAppl (fun, child0)
            case v : Range1 =>
                val child0 = TExpToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val fun = f.makeAFun ("Range", 2, false)
                f.makeAppl (fun, child0, child1)
            case _ =>
                sys.error ("unexpected value found for TRangeExp: " + value)
        }

    def TScalarVarToATerm (value : TScalarVar) : ATerm =
        value match {
            case v : Func =>
                val child0 = TVarToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val fun = f.makeAFun ("Func", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : TVarToTScalarVar =>
                TVarToATerm (v.arg0)
            case _ =>
                sys.error ("unexpected value found for TScalarVar: " + value)
        }

    def TArgTypeToATerm (value : TArgType) : ATerm =
        value match {
            case v : Window =>
                val child0 = TTypeToATerm (v.arg0)
                val fun = f.makeAFun ("Window", 1, false)
                f.makeAppl (fun, child0)
            case v : FunctionPtr =>
                val fun = f.makeAFun ("FunctionPtr", 0, false)
                f.makeAppl (fun)
            case v : Access =>
                val child0 = StringToATerm (v.arg0)
                val child1 = TArgTypeToATerm (v.arg1)
                val fun = f.makeAFun ("Access", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : CAccess =>
                val child0 = StringToATerm (v.arg0)
                val child1 = TArgTypeToATerm (v.arg1)
                val fun = f.makeAFun ("CAccess", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : Type =>
                val child0 = TTypeToATerm (v.arg0)
                val fun = f.makeAFun ("Type", 1, false)
                f.makeAppl (fun, child0)
            case v : TTypeToTArgType =>
                TTypeToATerm (v.arg0)
            case v : WindowArray =>
                val child0 = TRangeToATerm (v.arg0)
                val child1 = TRangeToATerm (v.arg1)
                val child2 = TTypeToATerm (v.arg2)
                val fun = f.makeAFun ("WindowArray", 3, false)
                f.makeAppl (fun, child0, child1, child2)
            case v : CArgument =>
                val child0 = TArgTypeToATerm (v.arg0)
                val child1 = TArgTypeToATerm (v.arg1)
                val fun = f.makeAFun ("CArgument", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : CBorder =>
                val child0 = TExpToATerm (v.arg0)
                val child1 = TArgTypeToATerm (v.arg1)
                val fun = f.makeAFun ("CBorder", 2, false)
                f.makeAppl (fun, child0, child1)
            case _ =>
                sys.error ("unexpected value found for TArgType: " + value)
        }

    def TEExpToATerm (value : TEExp) : ATerm =
        value match {
            case v : TExpToTEExp =>
                TExpToATerm (v.arg0)
            case v : None =>
                val fun = f.makeAFun ("None", 0, false)
                f.makeAppl (fun)
            case _ =>
                sys.error ("unexpected value found for TEExp: " + value)
        }

    def TExpListToATerm (value : TExpList) : ATerm =
        value match {
            case v : ListTExpToTExpList =>
                ListTExpToATerm (v.arg0)
            case _ =>
                sys.error ("unexpected value found for TExpList: " + value)
        }

    def TExpToATerm (value : TExp) : ATerm =
        value match {
            case v : Not =>
                val child0 = TExpToATerm (v.arg0)
                val fun = f.makeAFun ("Not", 1, false)
                f.makeAppl (fun, child0)
            case v : Mod =>
                val child0 = TExpToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val fun = f.makeAFun ("Mod", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : And =>
                val child0 = TExpToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val fun = f.makeAFun ("And", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : BitAnd =>
                val child0 = TExpToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val fun = f.makeAFun ("BitAnd", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : Mul =>
                val child0 = TExpToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val fun = f.makeAFun ("Mul", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : Neg =>
                val child0 = TExpToATerm (v.arg0)
                val fun = f.makeAFun ("Neg", 1, false)
                f.makeAppl (fun, child0)
            case v : False =>
                val fun = f.makeAFun ("False", 0, false)
                f.makeAppl (fun)
            case v : Real1 =>
                val child0 = TRealConstToATerm (v.arg0)
                val fun = f.makeAFun ("Real", 1, false)
                f.makeAppl (fun, child0)
            case v : CDecrementExp =>
                val child0 = TVarToATerm (v.arg0)
                val fun = f.makeAFun ("CDecrementExp", 1, false)
                f.makeAppl (fun, child0)
            case v : IfElseExp =>
                val child0 = TExpToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val child2 = TExpToATerm (v.arg2)
                val fun = f.makeAFun ("IfElseExp", 3, false)
                f.makeAppl (fun, child0, child1, child2)
            case v : BitOr =>
                val child0 = TExpToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val fun = f.makeAFun ("BitOr", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : Leq =>
                val child0 = TExpToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val fun = f.makeAFun ("Leq", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : Sub =>
                val child0 = TExpToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val fun = f.makeAFun ("Sub", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : Lt =>
                val child0 = TExpToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val fun = f.makeAFun ("Lt", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : Equ =>
                val child0 = TExpToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val fun = f.makeAFun ("Equ", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : Geq =>
                val child0 = TExpToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val fun = f.makeAFun ("Geq", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : IfKnownExp =>
                val child0 = TExpToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val child2 = TExpToATerm (v.arg2)
                val fun = f.makeAFun ("IfKnownExp", 3, false)
                f.makeAppl (fun, child0, child1, child2)
            case v : Known =>
                val child0 = TExpToATerm (v.arg0)
                val fun = f.makeAFun ("Known", 1, false)
                f.makeAppl (fun, child0)
            case v : Int =>
                val child0 = TIntConstToATerm (v.arg0)
                val fun = f.makeAFun ("Int", 1, false)
                f.makeAppl (fun, child0)
            case v : Neq =>
                val child0 = TExpToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val fun = f.makeAFun ("Neq", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : CAssign =>
                val child0 = TVarToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val fun = f.makeAFun ("CAssign", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : CIncrementExp1 =>
                val child0 = TVarToATerm (v.arg0)
                val fun = f.makeAFun ("CIncrementExp", 1, false)
                f.makeAppl (fun, child0)
            case v : Gt =>
                val child0 = TExpToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val fun = f.makeAFun ("Gt", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : Add =>
                val child0 = TExpToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val fun = f.makeAFun ("Add", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : Defined =>
                val child0 = TVarToATerm (v.arg0)
                val child1 = TRangeExpToATerm (v.arg1)
                val child2 = TRangeExpToATerm (v.arg2)
                val fun = f.makeAFun ("Defined", 3, false)
                f.makeAppl (fun, child0, child1, child2)
            case v : TScalarVarToTExp =>
                TScalarVarToATerm (v.arg0)
            case v : True =>
                val fun = f.makeAFun ("True", 0, false)
                f.makeAppl (fun)
            case v : Comma =>
                val child0 = TExpToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val fun = f.makeAFun ("Comma", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : Or =>
                val child0 = TExpToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val fun = f.makeAFun ("Or", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : Div =>
                val child0 = TExpToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val fun = f.makeAFun ("Div", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : CIncrementExp =>
                val child0 = TVarToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val fun = f.makeAFun ("CIncrementExp", 2, false)
                f.makeAppl (fun, child0, child1)
			case v : Parenthetical =>
				val child0 = TExpToATerm (v.arg0)
				val fun = f.makeAFun ("Parenthetical", 1, false)
                f.makeAppl (fun, child0)

            case _ =>
                sys.error ("unexpected value found for TExp: " + value)
        }

    def TDeclarationsToATerm (value : TDeclarations) : ATerm =
        value match {
            case v : Declarations =>
                val child0 = ListTDeclarationToATerm (v.arg0)
                val fun = f.makeAFun ("Declarations", 1, false)
                f.makeAppl (fun, child0)
            case _ =>
                sys.error ("unexpected value found for TDeclarations: " + value)
        }

    def TTypeToATerm (value : TType) : ATerm =
        value match {
            case v : Real =>
                val fun = f.makeAFun ("Real", 0, false)
                f.makeAppl (fun)
            case v : Border =>
                val child0 = TTypeToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val fun = f.makeAFun ("Border", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : CFunctionPtr =>
                val child0 = TVarToATerm (v.arg0)
                val fun = f.makeAFun ("CFunctionPtr", 1, false)
                f.makeAppl (fun, child0)
            case v : CArray =>
                val child0 = TTypeToATerm (v.arg0)
                val child1 = TExpListToATerm (v.arg1)
                val fun = f.makeAFun ("CArray", 2, false)
                f.makeAppl (fun, child0, child1)
			case v : CArray1 =>
                val child0 = TArgTypeToATerm (v.arg0)
                val child1 = TExpListToATerm (v.arg1)
                val fun = f.makeAFun ("CArray", 2, false)
                f.makeAppl (fun, child0, child1)

            case v : TVarToTType =>
                TVarToATerm (v.arg0)
            case v : Byte =>
                val fun = f.makeAFun ("Byte", 0, false)
                f.makeAppl (fun)
            case v : Array =>
                val child0 = TRangeListToATerm (v.arg0)
                val child1 = TTypeToATerm (v.arg1)
                val fun = f.makeAFun ("Array", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : Integer =>
                val fun = f.makeAFun ("Integer", 0, false)
                f.makeAppl (fun)
            case _ =>
                sys.error ("unexpected value found for TType: " + value)
        }

    def TFunctionArgsToATerm (value : TFunctionArgs) : ATerm =
        value match {
            case v : Arguments =>
                val child0 = ListTFunctionArgToATerm (v.arg0)
                val fun = f.makeAFun ("Arguments", 1, false)
                f.makeAppl (fun, child0)
            case _ =>
                sys.error ("unexpected value found for TFunctionArgs: " + value)
        }

    def TVarToATerm (value : TVar) : ATerm =
        value match {
            case v : Var =>
                val child0 = TIdToATerm (v.arg0)
                val fun = f.makeAFun ("Var", 1, false)
                f.makeAppl (fun, child0)
            case v : WindowAccessElement =>
                val child0 = TVarToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val child2 = TExpToATerm (v.arg2)
                val child3 = TRangeToATerm (v.arg3)
                val child4 = TRangeToATerm (v.arg4)
                val child5 = TTypeToATerm (v.arg5)
                val fun = f.makeAFun ("WindowAccessElement", 6, false)
                f.makeAppl (fun, child0, child1, child2, child3, child4, child5)
            case v : WindowAccessElement1 =>
                val child0 = TVarToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val child2 = TExpToATerm (v.arg2)
                val child3 = TRangeToATerm (v.arg3)
                val child4 = TRangeToATerm (v.arg4)
                val child5 = TTypeToATerm (v.arg5)
                val child6 = TLoopTypeToATerm (v.arg6)
                val fun = f.makeAFun ("WindowAccessElement", 7, false)
                f.makeAppl (fun, child0, child1, child2, child3, child4, child5, child6)
            case v : WindowAccessScalar1 =>
                val child0 = TVarToATerm (v.arg0)
                val child1 = TTypeToATerm (v.arg1)
                val child2 = StringToATerm (v.arg2)
                val fun = f.makeAFun ("WindowAccessScalar", 3, false)
                f.makeAppl (fun, child0, child1, child2)
            case v : Subscript =>
                val child0 = TVarToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val fun = f.makeAFun ("Subscript", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : WindowAccessScalar =>
                val child0 = TVarToATerm (v.arg0)
                val child1 = TTypeToATerm (v.arg1)
                val fun = f.makeAFun ("WindowAccessScalar", 2, false)
                f.makeAppl (fun, child0, child1)

			// HACK
			 case v : WindowAccessScalar2 =>
                val child0 = TVarToATerm (v.arg0)
                val child1 = TTypeToATerm (v.arg1)
                val child2 = TLoopTypeToATerm (v.arg2)
                val fun = f.makeAFun ("WindowAccessScalar", 3, false)
                f.makeAppl (fun, child0, child1, child2)

			// HACK
			case v : Parenthetical1 =>
				val child0 = TVarToATerm (v.arg0)
				val fun = f.makeAFun ("Parenthetical", 1, false)
	            f.makeAppl (fun, child0)

            case _ =>
                sys.error ("unexpected value found for TVar: " + value)
        }

    def TModuleToATerm (value : TModule) : ATerm =
        value match {
            case v : Module =>
                val child0 = ListTFunctionToATerm (v.arg0)
                val fun = f.makeAFun ("Module", 1, false)
                f.makeAppl (fun, child0)
            case _ =>
                sys.error ("unexpected value found for TModule: " + value)
        }

    def TFunctionToATerm (value : TFunction) : ATerm =
        value match {
            case v : Option =>
                val child0 = TCompilerOptionToATerm (v.arg0)
                val fun = f.makeAFun ("Option", 1, false)
                f.makeAppl (fun, child0)
            case v : Procedure =>
                val child0 = TVarToATerm (v.arg0)
                val child1 = TFunctionArgsToATerm (v.arg1)
                val child2 = TDeclarationsToATerm (v.arg2)
                val child3 = TStatementsToATerm (v.arg3)
                val child4 = TVarToATerm (v.arg4)
                val fun = f.makeAFun ("Procedure", 5, false)
                f.makeAppl (fun, child0, child1, child2, child3, child4)
            case _ =>
                sys.error ("unexpected value found for TFunction: " + value)
        }

    def TCompilerOptionToATerm (value : TCompilerOption) : ATerm =
        value match {
            case v : Dummy =>
                val fun = f.makeAFun ("Dummy", 0, false)
                f.makeAppl (fun)
            case v : MergeComplexMultiply =>
                val fun = f.makeAFun ("MergeComplexMultiply", 0, false)
                f.makeAppl (fun)
            case _ =>
                sys.error ("unexpected value found for TCompilerOption: " + value)
        }

    def TFunctionArgToATerm (value : TFunctionArg) : ATerm =
        value match {
            case v : Argument =>
                val child0 = TVarToATerm (v.arg0)
                val child1 = TArgTypeToATerm (v.arg1)
                val fun = f.makeAFun ("Argument", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : Argument1 =>
                val child0 = TVarListToATerm (v.arg0)
                val child1 = TArgTypeToATerm (v.arg1)
                val fun = f.makeAFun ("Argument", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : InOut =>
                val child0 = TVarListToATerm (v.arg0)
                val child1 = TArgTypeToATerm (v.arg1)
                val fun = f.makeAFun ("InOut", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : In =>
                val child0 = TVarListToATerm (v.arg0)
                val child1 = TArgTypeToATerm (v.arg1)
                val fun = f.makeAFun ("In", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : Out =>
                val child0 = TVarListToATerm (v.arg0)
                val child1 = TArgTypeToATerm (v.arg1)
                val fun = f.makeAFun ("Out", 2, false)
                f.makeAppl (fun, child0, child1)

			// HACK:
			case v : CArgument =>
				val child0 = TArgTypeToATerm (v.arg0)
				val child1 = TArgTypeToATerm (v.arg1)
 				val fun = f.makeAFun ("CArgument", 2, false)
                f.makeAppl (fun, child0, child1)

            case _ =>
                sys.error ("unexpected value found for TFunctionArg: " + value)
        }

    def TLoopTypeToATerm (value : TLoopType) : ATerm =
        value match {
            case v : Index =>
                val fun = f.makeAFun ("Index", 0, false)
                f.makeAppl (fun)
            case v : RowColumn =>
                val fun = f.makeAFun ("RowColumn", 0, false)
                f.makeAppl (fun)
            case _ =>
                sys.error ("unexpected value found for TLoopType: " + value)
        }

    def TDeclarationToATerm (value : TDeclaration) : ATerm =
        value match {
            case v : Declaration =>
                val child0 = TVarListToATerm (v.arg0)
                val child1 = TTypeToATerm (v.arg1)
                val fun = f.makeAFun ("Declaration", 2, false)
                f.makeAppl (fun, child0, child1)
			case v : Declaration1 =>
			 	val child0 = TVarToATerm (v.arg0)
                val child1 = TTypeToATerm (v.arg1)
                val fun = f.makeAFun ("Declaration", 2, false)
               f.makeAppl (fun, child0, child1)
			case v : CDeclaration =>
                val child0 = TTypeToATerm (v.arg0)
                val child1 = TTypeToATerm (v.arg1)
                val fun = f.makeAFun ("CDeclaration", 2, false)
                f.makeAppl (fun, child0, child1)
            case _ =>
                sys.error ("unexpected value found for TDeclaration: " + value)
        }

    def TStatementsToATerm (value : TStatements) : ATerm =
        value match {
            case v : Statements =>
                val child0 = ListTStatementToATerm (v.arg0)
                val fun = f.makeAFun ("Statements", 1, false)
                f.makeAppl (fun, child0)
            case _ =>
                sys.error ("unexpected value found for TStatements: " + value)
        }

    def TRangeListToATerm (value : TRangeList) : ATerm =
        value match {
            case v : ListTRangeToTRangeList =>
                ListTRangeToATerm (v.arg0)
            case _ =>
                sys.error ("unexpected value found for TRangeList: " + value)
        }

    def TRangeToATerm (value : TRange) : ATerm =
        value match {
            case v : Range2 =>
                val child0 = TExpToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val fun = f.makeAFun ("Range", 2, false)
                f.makeAppl (fun, child0, child1)
            case _ =>
                sys.error ("unexpected value found for TRange: " + value)
        }

    def TStatementToATerm (value : TStatement) : ATerm =
        value match {
            case v : Assert =>
                val child0 = TExpToATerm (v.arg0)
                val fun = f.makeAFun ("Assert", 1, false)
                f.makeAppl (fun, child0)
            case v : Attribute =>
                val child0 = TExpToATerm (v.arg0)
                val child1 = TStatementsToATerm (v.arg1)
                val fun = f.makeAFun ("Attribute", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : While =>
                val child0 = TExpToATerm (v.arg0)
                val child1 = TStatementsToATerm (v.arg1)
                val fun = f.makeAFun ("While", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : IfKnownStmt =>
                val child0 = TExpToATerm (v.arg0)
                val child1 = TStatementsToATerm (v.arg1)
                val child2 = TStatementsToATerm (v.arg2)
                val fun = f.makeAFun ("IfKnownStmt", 3, false)
                f.makeAppl (fun, child0, child1, child2)
            case v : IfElse =>
                val child0 = TExpToATerm (v.arg0)
                val child1 = TStatementsToATerm (v.arg1)
                val child2 = TStatementsToATerm (v.arg2)
                val fun = f.makeAFun ("IfElse", 3, false)
                f.makeAppl (fun, child0, child1, child2)
            case v : Statement =>
                val child0 = TExpToATerm (v.arg0)
                val fun = f.makeAFun ("Statement", 1, false)
                f.makeAppl (fun, child0)
            case v : Comment =>
                val child0 = TCommentStatementToATerm (v.arg0)
                val fun = f.makeAFun ("Comment", 1, false)
                f.makeAppl (fun, child0)
            case v : CFor =>
                val child0 = TEExpToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val child2 = TEExpToATerm (v.arg2)
                val child3 = TStatementsToATerm (v.arg3)
                val fun = f.makeAFun ("CFor", 4, false)
                f.makeAppl (fun, child0, child1, child2, child3)
			case v : CFor1 =>
                val child0 = TStatementsToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val child2 = TStatementsToATerm (v.arg2)
                val child3 = TStatementsToATerm (v.arg3)
                val fun = f.makeAFun ("CFor", 4, false)
                f.makeAppl (fun, child0, child1, child2, child3)
            case v : CIncrementStmt =>
                val child0 = TVarToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val fun = f.makeAFun ("CIncrementStmt", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : ApplyLoop =>
                val child0 = TLoopTypeToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val child2 = TExpToATerm (v.arg2)
                val child3 = TExpToATerm (v.arg3)
                val child4 = TExpToATerm (v.arg4)
                val child5 = TStatementsToATerm (v.arg5)
                val fun = f.makeAFun ("ApplyLoop", 6, false)
                f.makeAppl (fun, child0, child1, child2, child3, child4, child5)
            case v : Assign =>
                val child0 = TScalarVarToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val fun = f.makeAFun ("Assign", 2, false)
                f.makeAppl (fun, child0, child1)
            case v : CIncrementStmt1 =>
                val child0 = TVarToATerm (v.arg0)
                val fun = f.makeAFun ("CIncrementStmt", 1, false)
                f.makeAppl (fun, child0)
            case v : For =>
                val child0 = TVarToATerm (v.arg0)
                val child1 = TExpToATerm (v.arg1)
                val child2 = TExpToATerm (v.arg2)
                val child3 = TStatementsToATerm (v.arg3)
                val fun = f.makeAFun ("For", 4, false)
                f.makeAppl (fun, child0, child1, child2, child3)
            case v : If =>
                val child0 = TExpToATerm (v.arg0)
                val child1 = TStatementsToATerm (v.arg1)
                val fun = f.makeAFun ("If", 2, false)
                f.makeAppl (fun, child0, child1)
            case _ =>
                sys.error ("unexpected value found for TStatement: " + value)
        }

    def TVarListToATerm (value : TVarList) : ATerm =
        value match {
            case v : VarList =>
                val child0 = ListTVarToATerm (v.arg0)
                val fun = f.makeAFun ("VarList", 1, false)
                f.makeAppl (fun, child0)
            case _ =>
                sys.error ("unexpected value found for TVarList: " + value)
        }

    def StringToATerm (value : String) : ATerm =
        f.makeAppl (f.makeAFun (value, 0, true)) 

    def TRealConstToATerm (value : TRealConst) : ATerm =
        StringToATerm (value)

    def TIntConstToATerm (value : TIntConst) : ATerm =
        StringToATerm (value)

    def TIdToATerm (value : TId) : ATerm =
        StringToATerm (value)

    def TCommentStatementToATerm (value : TCommentStatement) : ATerm =
        StringToATerm (value)

    def ListTStatementToATerm (value : List[TStatement]) : ATermList =
        if (value.isEmpty)
            f.makeList ()
        else {
            val h = TStatementToATerm (value.head)
            val t = ListTStatementToATerm (value.tail)
            f.makeList (h, t)
        }

    def ListTRangeToATerm (value : List[TRange]) : ATermList =
        if (value.isEmpty)
            f.makeList ()
        else {
            val h = TRangeToATerm (value.head)
            val t = ListTRangeToATerm (value.tail)
            f.makeList (h, t)
        }

    def ListTDeclarationToATerm (value : List[TDeclaration]) : ATermList =
        if (value.isEmpty)
            f.makeList ()
        else {
            val h = TDeclarationToATerm (value.head)
            val t = ListTDeclarationToATerm (value.tail)
            f.makeList (h, t)
        }

    def ListTFunctionArgToATerm (value : List[TFunctionArg]) : ATermList =
        if (value.isEmpty)
            f.makeList ()
        else {
            val h = TFunctionArgToATerm (value.head)
            val t = ListTFunctionArgToATerm (value.tail)
            f.makeList (h, t)
        }

    def ListTFunctionToATerm (value : List[TFunction]) : ATermList =
        if (value.isEmpty)
            f.makeList ()
        else {
            val h = TFunctionToATerm (value.head)
            val t = ListTFunctionToATerm (value.tail)
            f.makeList (h, t)
        }

    def ListTVarToATerm (value : List[TVar]) : ATermList =
        if (value.isEmpty)
            f.makeList ()
        else {
            val h = TVarToATerm (value.head)
            val t = ListTVarToATerm (value.tail)
            f.makeList (h, t)
        }

    def ListTExpToATerm (value : List[TExp]) : ATermList =
        if (value.isEmpty)
            f.makeList ()
        else {
            val h = TExpToATerm (value.head)
            val t = ListTExpToATerm (value.tail)
            f.makeList (h, t)
        }

}